package jdbc;

//JDBC提高接口规范：java.sql.*
import java.sql.*; 	//自动把这个包下的所有类都导入

/**
	@author 作者： CGB.NUTONY 
	@author 邮箱：chenzs@tedu.cn
	@version 版本：1.0 上午11:53:50
	@desc 功能：statement对象不安全，黑客侵入，SQL注入
	
	怎么解决SQL注入安全问题？
	需要使用另外一个对象PreparedStatement，预编译语句对象
	它改变SQL语句，把参数部分变成？问号，然后单独设置这个值
	单独使用PreparedStatement执行SQL
*/

public class TestPS {
	public static void main(String[] args) throws Exception {
		Class.forName("com.mysql.cj.jdbc.Driver");	//固定值，注册
		String url = "jdbc:mysql://localhost:3307/py-school-db"
				+ "?characterEncoding=utf8"
				+ "&serverTimezone=Asia/Shanghai";			
		String user = "root";	//用户名
		String password = "root"; //密码

		Connection cn = DriverManager.getConnection(url, user, password);
		//Statement stat = cn.createStatement();
		
		
		//SQL注入，本应该获取一条记录，但我可以获取所有值
		//String condition = "陈冰";  //用户输入值
		String condition = "陈冰' OR 1=1 OR '"; 
		
		//用户输入字符串：陈冰，SQL底层会自动两边加单撇
		//String sql = "select * from teachers where tname='" + condition + "'";		//注意里面不需要;结尾
		//第二步：改sql
		String sql = "select * from teachers where tname=?";
		
		//第一步：预编译对象
		PreparedStatement ps = cn.prepareStatement(sql);
		//第三步：可以支持多个?，按问号顺序填写
		ps.setString(1, condition);
		
		//ResultSet rs = stat.executeQuery(sql);		//执行查询的sql语句
		//第四步：无参数，换成ps
		ResultSet rs = ps.executeQuery();
		System.out.println("查询SQL语句："+sql);
		
		int cols = rs.getMetaData().getColumnCount();
		System.out.println("表的字段个数：" + cols);
		
		for(int i=1; i<=cols; i++) {
			System.out.print( rs.getMetaData().getColumnName(i) +"\t" );
		}
		
		while( rs.next() ) {
			System.out.println();   //换行
			for(int i=1; i<=cols; i++) {
				System.out.print( rs.getString(i)+"\t" );
			}
		}
	}
}





